package com.beiben.workflow.service.impl;

import com.beiben.common.GlobalConstant;
import com.beiben.project.domain.Project;
import com.beiben.project.mapper.ProjectMapper;
import com.beiben.work.process.domain.FileProcessUser;
import com.beiben.work.process.mapper.FileProcessUserMapper;
import com.beiben.workflow.domain.*;
import com.beiben.workflow.mapper.WfApplyMapper;
import com.beiben.workflow.mapper.WfCheckLogMapper;
import com.beiben.workflow.mapper.WfCheckMapper;
import com.beiben.workflow.service.IWfApplyService;
import com.beiben.workflow.service.IWfCheckLogService;
import com.beiben.workflow.service.IWfCheckService;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 审核日志Service业务层处理
 *
 * @author 熊国强
 * @date 2020-12-17
 */
@Service
public class WfCheckLogServiceImpl implements IWfCheckLogService {
    @Autowired
    private WfCheckLogMapper wfCheckLogMapper;

    @Autowired
    private WfCheckMapper wfCheckMapper;

    @Autowired
    private IWfApplyService wfApplyService;

    @Autowired
    private IWfCheckService wfCheckService;

    @Autowired
    private WfApplyMapper wfApplyMapper;

    @Autowired
    private FileProcessUserMapper fileProcessUserMapper;

    @Autowired
    private ProjectMapper projectMapper;

    /**
     * 查询审核日志
     *
     * @param logId 审核日志ID
     * @return 审核日志
     */
    @Override
    public WfCheckLog selectWfCheckLogById(Long logId) {
        return wfCheckLogMapper.selectWfCheckLogById(logId);
    }

    /**
     * 查询审核日志列表
     *
     * @param wfCheckLog 审核日志
     * @return 审核日志
     */
    @Override
    public List<WfCheckLogVo> selectWfCheckLogList(WfCheckLog wfCheckLog) {
        return wfCheckLogMapper.selectWfCheckLogList(wfCheckLog);
    }

    /**
     * 新增审核日志
     *
     * @param wfCheckLog 审核日志
     * @return 结果
     */
    @Override
    public int insertWfCheckLog(WfCheckLog wfCheckLog) {
        wfCheckLog.setCreateTime(DateUtils.getNowDate());
        //修改源数据状态
        this.updateSourceState(wfCheckLog.getApplyId(), Integer.parseInt(wfCheckLog.getState()));
        return wfCheckLogMapper.insertWfCheckLog(wfCheckLog);
    }

    /**
     * 修改审核日志
     *
     * @param wfCheckLog 审核日志
     * @return 结果
     */
    @Override
    public int updateWfCheckLog(WfCheckLog wfCheckLog) {
        return wfCheckLogMapper.updateWfCheckLog(wfCheckLog);
    }

    /**
     * 批量删除审核日志
     *
     * @param logIds 需要删除的审核日志ID
     * @return 结果
     */
    @Override
    public int deleteWfCheckLogByIds(Long[] logIds) {
        return wfCheckLogMapper.deleteWfCheckLogByIds(logIds);
    }

    /**
     * 删除审核日志信息
     *
     * @param logId 审核日志ID
     * @return 结果
     */
    @Override
    public int deleteWfCheckLogById(Long logId) {
        return wfCheckLogMapper.deleteWfCheckLogById(logId);
    }


    /**
     * 审批
     *
     * @param wfCheckLog checkId applyId
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, timeout = 72000, rollbackFor = Exception.class)
    public int approve(WfCheckLog wfCheckLog) {
        //校验申请状态
        if (!"2".equals(wfCheckLog.getState()) && !"3".equals(wfCheckLog.getState()) && !"5".equals(wfCheckLog.getState())) {
            throw new RuntimeException("当前审批不和规，请查证后再试！");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        wfCheckLog.setCheckUserId(loginUser.getUser().getUserId());
        //校验审批
        int count = wfCheckMapper.verifyCheck(wfCheckLog.getCheckUserId(), wfCheckLog.getCheckId());
        if (count == 0) {
            throw new RuntimeException("当前审批不和规，请查证后再试！");
        } else if (count > 1) {
            throw new RuntimeException("审批流程异常，请联系管理员！");
        }
        //申请状态
        String applyState;
        //判断当前状态是否为通过
        String state = wfCheckLog.getState();
        if (StringUtils.isNotEmpty(state) && WorkFlowConstant.APPLY_STATE_PASS.equals(state)) {
            //判断是否为最后一级审批
            int lastCount = wfCheckMapper.verifyFinalCheck(wfCheckLog.getCheckId());
            if (lastCount == 0) {
                applyState = WorkFlowConstant.APPLY_STATE_PASS;
            } else {
                applyState = WorkFlowConstant.APPLY_STATE_CHECK;
            }
        } else {
            applyState = wfCheckLog.getState();
        }

        //插入审批日志
        wfCheckLog.setCreateTime(DateUtils.getNowDate());
        wfCheckLog.setType(WorkFlowConstant.LOG_RECORD_TYPE_CHECK);
        int result = wfCheckLogMapper.insertWfCheckLog(wfCheckLog);

        //修改流程状态
        wfCheckService.updateWfCheckState(wfCheckLog);

        //修改申请状态
        wfApplyService.updateApplyState(wfCheckLog.getApplyId(), applyState);

        //修改源数据状态
        this.updateSourceState(wfCheckLog.getApplyId(), Integer.parseInt(applyState));
        addApplyAndCheck(wfCheckLog);
        return result;
    }

    /**
     * 判断是否已全部完成，是否需要生成新的申请及审核单
     */
    public void addApplyAndCheck(WfCheckLog wfCheckLog) {
        //  判断为审核通过，则判断是否是项目工作，是项目工作，判断是否所有工作已完成，全部已完成则自动生成一条申请记录，申请人为当前审核人，审核人为节点的负责人。
        WfApply wfa = wfApplyMapper.selectWfApplyByCheckId(wfCheckLog.getCheckId());
        switch (wfa.getApplyType()) {
            case WorkFlowConstant.APPLT_TYPE_PROJECT://项目工作
                this.isTheProjectWorkCompleted(wfa.getTableId(), wfCheckLog.getCheckUserId());
                break;
            // TODO: 2021/1/6 如果为节点审核工作，审核状态为通过，则判断时候左右评级节点已全部完成，全部完成自动提交上一条节点的审核，申请人为当前审核人，审核人为节点负责人。
            case WorkFlowConstant.APPLY_TYPE_PROJECT_POINT://项目节点工作
                if (wfa.getTableName().equals(GlobalConstant.PM_PROJECT)) {
                    this.isTheProjectNodeCompleted(wfa.getTableId(), wfCheckLog.getCheckUserId());
                }
                break;
        }
    }

    /**
     * 判断同级工作是否全部完成
     * <p>
     * 工作的审核人就是 节点审核的申请人
     *
     * @param itemId
     * @param applyUserId
     */
    @Override
    public void isTheProjectWorkCompleted(Long itemId, Long applyUserId) {
        List<FileProcessUser> fUserlist = fileProcessUserMapper.selectFileProcessUserPeerByItemId(String.valueOf(itemId), WorkFlowConstant.APPLT_TYPE_PROJECT);
        boolean isFinish = true;
        Long workId = null;
        for (FileProcessUser fpu : fUserlist) {
            workId = fpu.getWorkId();
            if (5 != fpu.getState()) {
                isFinish = false;
                break;
            }
        }
        // 查询于工作统计的项目节点 是否都完成
        List<Project> pList = projectMapper.selectProjectListByParentIdDoning(workId);
        if (null != pList && pList.size() > 0) {
            isFinish = false;
        }
        if (isFinish) {
            //  自动生成一条申请记录，申请人为当前审核人，审核人为节点的负责人
            Project project = projectMapper.selectProjectById(workId);
            WfApply wfApply = new WfApply();
            wfApply.setTableId(workId);
            wfApply.setTableName(GlobalConstant.PM_PROJECT);
            wfApply.setApplyUserId(applyUserId);
            wfApply.setApplyType(WorkFlowConstant.APPLY_TYPE_PROJECT_POINT);
            wfApply.setState("1");
            wfApply.setCreateTime(DateUtils.getNowDate());
            wfApply.setRemark(project.getProjectName());
            wfApplyMapper.insertWfApply(wfApply);
            WfCheck wfCheck = new WfCheck();
            wfCheck.setApplyId(wfApply.getApplyId());
            wfCheck.setState("1");
            wfCheck.setParentId(0l);
            wfCheck.setCheckUserId(project.getTechnologyLeaderUserId());
            wfCheckMapper.insertWfCheck(wfCheck);
            //修改源数据状态
            project.setState(Integer.parseInt(WorkFlowConstant.APPLY_STATE_CHECK));
            projectMapper.updateProject(project);
        }
    }

    /**
     * 判断统计节点是否全部完成
     *
     * @param projectId
     * @param applyUserId
     */
    @Override
    public void isTheProjectNodeCompleted(Long projectId, Long applyUserId) {
        Project project = projectMapper.selectProjectById(projectId);
        if (0 != project.getParentId()) {
            List<Project> pList = projectMapper.selectProjectListByParentIdDoning(project.getParentId());
            List<FileProcessUser> fUserlist = fileProcessUserMapper.selectFileProcessUserByWorkIdsIsComplete(new Long[]{project.getParentId()});
            if ((null == pList || pList.size() <= 0) && (fUserlist == null || fUserlist.size() <= 0)) {// TODO: 2021/1/7 新增上级审核
                Project parentProject = projectMapper.selectProjectById(project.getParentId());
                WfApply wfApply = new WfApply();
                wfApply.setTableId(project.getParentId());
                wfApply.setTableName(GlobalConstant.PM_PROJECT);
                wfApply.setApplyUserId(applyUserId);
                wfApply.setApplyType(WorkFlowConstant.APPLY_TYPE_PROJECT_POINT);
                wfApply.setState("1");
                wfApply.setCreateTime(DateUtils.getNowDate());
                wfApply.setRemark(parentProject.getProjectName());
                wfApplyMapper.insertWfApply(wfApply);
                WfCheck wfCheck = new WfCheck();
                wfCheck.setApplyId(wfApply.getApplyId());
                wfCheck.setState("1");
                wfCheck.setParentId(0l);
                wfCheck.setCheckUserId(project.getTechnologyLeaderUserId());
                wfCheckMapper.insertWfCheck(wfCheck);
                //修改源数据状态
                project.setState(Integer.parseInt(WorkFlowConstant.APPLY_STATE_CHECK));
                projectMapper.updateProject(project);
            }
        }
    }

    @Override
    public int updateSourceState(Long applyId, Integer applyState) {
        int result = 0;
        //查询申请 根据table_name 修改对应表的数据状态
        WfApply wfApply = wfApplyService.selectWfApplyById(applyId);
        if (wfApply == null) {
            throw new BaseException("申请已删除，不存在此申请！applyId:" + applyId);
        }
        //源数据id
        Long sourceId = wfApply.getTableId();
        //源数据表id
        String tableName = wfApply.getTableName();
        if (GlobalConstant.PM_PROJECT.equals(tableName)) {
            //修改项目表
            ProjectMapper projectMapper = SpringUtils.getBean(ProjectMapper.class);
            Project project = new Project();
            project.setProjectId(sourceId);
            project.setState(applyState);
            if (5 == applyState) {
                project.setRelFinishTime(DateUtils.getNowDate());
            }
            result = projectMapper.updateProject(project);
        } else {
            //修改工作表
            FileProcessUserMapper bean = SpringUtils.getBean(FileProcessUserMapper.class);
            FileProcessUser project = new FileProcessUser();
            project.setItemId(sourceId);
            project.setState(applyState);
            if (5 == applyState) {
                project.setRealFinishTime(DateUtils.getNowDate());
            }
            result = bean.updateFileProcessUser(project);
        }
        return result;
    }

    @Override
    public int approve(Long tableId, String tableName) {
        WfCheckLog wfCheckLog = wfCheckLogMapper.selectWfCheckByTableInfo(tableId, tableName);
        if (wfCheckLog == null) {
            throw new BaseException("请提交审核！");
        }
        wfCheckLog.setState(WorkFlowConstant.APPLY_STATE_PASS);
        return this.approve(wfCheckLog);
    }
}
